#include "CGamePlayState.h"
#include "CMainMenuState.h"
#include "CGame.h"
#include "SGD Wrappers\CSGD_TextureManager.h"
#include "SGD Wrappers\CSGD_Direct3D.h"
#include "SGD Wrappers\CSGD_DirectInput.h"
#include "SGD Wrappers\CSGD_FModManager.h"
#include "SGD_Math.h"
#include "ObjectFactory.h"
#include "ObjectManager.h"
#include "Messaging\MessageSystem.h"
#include "Messaging\Messages.h"
#include "Messaging\EventSystem.h"
#include "CHud.h"
#include "CWorldManager.h"

#include "CBitmapFont.h"
#include "Camera.h"

#include "CPlayer.h"
#include "CEnemy.h"
#include <fstream>
using namespace std;

#include "ParticleManager.h"

#include "CProximityRune.h"

CGamePlayState::CGamePlayState( void )
{
}
CGamePlayState::~CGamePlayState(void)
{
	
}

CGamePlayState* CGamePlayState::GetInstance( void )
{
	//	Lazy instantiation
	static CGamePlayState instance;
	return &instance;
}
void CGamePlayState::Enter(void)
{
	bIsPaused				= false;
	bDebugModeOn			= false;
	SetGameIsOver(false);
	m_HudObject				= NULL;
	m_pPlayerOne			= NULL;
	m_pPlayerTwo			= NULL;
	

	CWorldManager::GetInstance()->LoadStage("resources//data//example4.xml");

	m_nCursorID = CSGD_TextureManager::GetInstance()->LoadTexture( "resources//graphics//SGD_MenuCursor.png" );	
	//m_hObject->CreateHudObject("resources//graphics//Spell-slingers.png",1200,1600,0,0,1);

	// assign local variables to managers so you don't have to do a function call every time you want to use that manager
	m_pMS	= MessageSystem::GetInstance();
	m_pES	= EventSystem::GetInstance();
	m_pOF	= CObjectFactory::GetInstance();
	m_pOM	= CObjectManager::GetInstance();
	m_HudObject = CHud::GetInstance();

	m_nBGM[0] =   CSGD_FModManager::GetInstance()->LoadSound("resources//music//StS_02_chapter_01_-_ideal.OGG", FMOD_LOOP_NORMAL);
	CSGD_FModManager::GetInstance()->SetVolume(m_nBGM[0],CGame::GetInstance()->GetMusicVolume());
	CSGD_FModManager::GetInstance()->SetPan(m_nBGM[0],CGame::GetInstance()->GetPanVolume());
	
	m_nScreenWidth = CGame::GetInstance()->GetScreenW();
	m_nScreenHeight = CGame::GetInstance()->GetScreenH();

	CWorldManager::GetInstance()->LoadStage("resources//data//example4.xml");

	/*CHud::GetInstance()->CreateHudObject("A button.png",  83, 568, 32, 32, 1.0f, 1.0f, 0, D3DCOLOR_XRGB(255, 255, 255));
	CHud::GetInstance()->CreateHudObject("B button.png", 183, 568, 32, 32, 1.0f, 1.0f, 0, D3DCOLOR_XRGB(255, 255, 255));
	CHud::GetInstance()->CreateHudObject("X button.png", 283, 568, 32, 32, 1.0f, 1.0f, 0, D3DCOLOR_XRGB(255, 255, 255));
	CHud::GetInstance()->CreateHudObject("Y button.png", 383, 568, 32, 32, 1.0f, 1.0f, 0, D3DCOLOR_XRGB(255, 255, 255));
	CHud::GetInstance()->CreateHudObject("hud bar border.png", 0, 499, 800, 100, 1.0f, 1.0f, 0, D3DCOLOR_XRGB(255, 255, 255));*/
	//m_HudObject->LoadHUDObjects();
		 
	//	Initialize message system
	m_pMS->InitMessageSystem( CGamePlayState::MessageProc );

	m_pPlayerOne = m_pOF->CreatePlayer();
	m_pPlayerOne->SetPlayerNumber(1);
	m_pPlayerOne->SetScale(2.0f);
	m_pPlayerOne->SetSpellSlot(0, new CProximityRune);
	m_pOM->AddObject(m_pPlayerOne, OMF_PLAYER, RL_MAIN);

	// Register the player's ship with the object factory and add it to the object manager
	/*CSGD_ObjectFactory<std::string, CBase>::GetInstance()->RegisterClassType<CPlayerShip>("CPlayerShip");

	m_pPlayerShip = (CPlayerShip*)CSGD_ObjectFactory<std::string, CBase>::GetInstance()->CreateObject("CPlayerShip");
	m_pPlayerShip->Reset();
	CSGD_ObjectManager::GetInstance()->AddObject(m_pPlayerShip);

	m_pPlayerShip->Release();*/

	// Register the player's black bullets with the object factory and add it to the object manager
	/*CSGD_ObjectFactory<std::string, CBase>::GetInstance()->RegisterClassType<CBlackBullet>("CBlackBullet");

	m_pBlackBullet = (CBlackBullet*)CSGD_ObjectFactory<std::string, CBase>::GetInstance()->CreateObject("CBlackBullet");
	m_pBlackBullet->SetVelX(0);
	m_pBlackBullet->SetVelY(-150);
	m_pBlackBullet->SetWidth(24);
	m_pBlackBullet->SetHeight(22);
	m_pBlackBullet->SetColor(CGame::GetInstance()->ReturnBlack() );*/


	// TODO: Resgister the events being used by this state
	//CSGD_EventSystem::GetInstance()->RegisterClient("playerIsDead", this);
	m_pES->RegisterClient(REDUCE_ENEMY_HEALTH, this);

	m_nFrameCounter = 0;
	m_dwLastUpdateTime = 0;
	m_dwElapsedTime = 0;

	CSGD_FModManager::GetInstance()->PlaySound(m_nBGM[0]);

	CGame::GetInstance()->SetGameTime(0);
	
	
	//ParticleManager::GetInstance()->Load("resources/data/Test12.xml");

}
bool CGamePlayState::Input(void)
{
	// pressing P or Escape will pause/unpause the game
	if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_P) || CSGD_DirectInput::GetInstance()->KeyPressed(DIK_ESCAPE))
	{
		bIsPaused = !bIsPaused;
		m_nMenuSelection = PAUSE_RESUME;

	}

	// if the user presses ALT + TAB, the game is paused
	if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_TAB) && 
		(CSGD_DirectInput::GetInstance()->KeyDown(DIK_LALT) || CSGD_DirectInput::GetInstance()->KeyDown(DIK_RALT)))
	{
		bIsPaused = true;
	}
	//////////////////////////////////////
	//
	//	PAUSE THE GAME
	//
	//////////////////////////////////////
	if (bIsPaused)
	{
		//move up the menu
		if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_UP) || CSGD_DirectInput::GetInstance()->KeyPressed(DIK_W) )
		{
			m_nMenuSelection -= 1;

			if( m_nMenuSelection == -1 )
			{
				m_nMenuSelection = PAUSE_EXIT;
			}

		}

		//move down the menu
		if(CSGD_DirectInput::GetInstance()->KeyPressed(DIK_DOWN) || CSGD_DirectInput::GetInstance()->KeyPressed(DIK_S) )
		{
			m_nMenuSelection += 1;

			if( m_nMenuSelection == NUM_PAUSE_OPTIONS )
			{
				m_nMenuSelection = PAUSE_RESUME;
			}

		}

		if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN) )
		{
			switch( m_nMenuSelection )
			{
			case PAUSE_RESUME:
				{
					//unpause the game
					bIsPaused = false;
				}
				break;
			case PAUSE_EXIT:
				{
					// return to the main menu
					CGame::GetInstance()->ChangeState( CMainMenuState::GetInstance() );
				}
				break;
			}
		}
	}
	//////////////////////////////////////
	//
	//	PLAY THE GAME
	//
	//////////////////////////////////////
	else
	{
		//TODO: Press buttons to do stuff
		HandlePlayerOneInput();


		if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_R) )
		{
			CPlayer* player = CObjectFactory::GetInstance()->CreatePlayer();
			player->SetPlayerNumber(1);
			player->SetPosition(100, 100);
			player->SetScale(2.0f);
			player->SetIsSlowed(true);
			//player->SetIsSprinting(true);
			player->SetIsEmpowered(true);
			player->SetHasArmor(true);
			player->SetMana(100);
			CObjectManager::GetInstance()->AddObject(player, OMF_PLAYER, RL_MAIN);
		}
		if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_T) )
		{
			CPlayer* player = CObjectFactory::GetInstance()->CreatePlayer();
			player->SetPlayerNumber(2);
			player->SetPosition(200, 200);
			player->SetScale(2.0f);
			//player->SetIsSlowed(true);
			player->SetIsSprinting(true);
			player->SetIsEmpowered(true);
			player->SetHasArmor(true);
			player->SetMana(50);
			player->SetRotation(-30.0f);
			CObjectManager::GetInstance()->AddObject(player, OMF_PLAYER, RL_MAIN);
		}

		if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_G) )
		{
			//m_pMS->SendMsg(new CCreatePlayerMsg(25, 25));
		}
		if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_U) )
		{
			m_pES->SendEvent(REDUCE_ENEMY_HEALTH,(void*)this);
		}

		if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_Y) )
		{
			CEnemy* enemy = CObjectFactory::GetInstance()->CreateEnemy();
			enemy->SetPosition(400, 100);
			enemy->SetScale(2.0f);
			CObjectManager::GetInstance()->AddObject(enemy, OMF_ENEMY, RL_WORLD_TILES);
		}

	}


	if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_HOME))
	{
		bDebugModeOn = !bDebugModeOn;
		//CSGD_EventSystem::GetInstance()->SendEvent("toggleDebugDisplay.debug",(void*)this);
	}

	///////////////////////////////
	//
	//	CHEAT CODES
	//////////////////////////////
	

	return true;
}
void CGamePlayState::Update(float fElapsedTime)
{
	// Only update if the game isn't paused
	if (bIsPaused == false)
	{
		//TODO: Make these managers

	//	ParticleManager::GetInstance()->Update(fElapsedTime);
		CObjectManager::GetInstance()->UpdateObjects(fElapsedTime, OMF_ALL);
		//CSGD_ObjectManager::GetInstance()->CheckCollisions();
		//CSGD_ObjectManager::GetInstance()->PrintObjectsToConsole();
		m_pES->ProcessEvents();
		m_pMS->ProcessMessages();
	
	}

}
void CGamePlayState::Render(void)
{	
//<<<<<<< .mine
		CWorldManager::GetInstance()->Render();
		//CObjectManager::GetInstance()->RenderObjectsByGroup(OMF_ALL);
		CObjectManager::GetInstance()->RenderObjectsByLayer();
		CSGD_Direct3D::GetInstance()->GetSprite()->Flush();
	//	ParticleManager::GetInstance()->Render();

		//////////////////////////////////////
		//
		//	PAUSE THE GAME
		//
		//////////////////////////////////////
		if (bIsPaused)
		{
			CBitmapFont::GetInstance()->SetScale(1.0f);
			RECT rRect = {0, 240, CGame::GetInstance()->GetPlayW(), 300};
			CBitmapFont::GetInstance()->PrintInRect("Resume\nMain Menu", &rRect, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));
			//BF.PrintText("Resume", 75, 10, 1.25f, D3DCOLOR_XRGB(255, 255, 255), true, true);
			//BF.PrintText("Main Menu", 125, 270, 1.25f, D3DCOLOR_XRGB(255, 255, 255), true);

			switch(m_nMenuSelection)
			{
			case PAUSE_RESUME:
				{
					CSGD_TextureManager::GetInstance()->Draw(m_nCursorID, 125, 240 );
				}
				break;

			case PAUSE_EXIT:
				{
					CSGD_TextureManager::GetInstance()->Draw(m_nCursorID, 125, 305 );
				}
				break;
			}
		}
		///////////////////////////////////////
		//
		//	"HUD" INFORMATION
		//
		//////////////////////////////////////
		m_HudObject->DrawHUDBar(m_pPlayerOne);
		//int hudborder = CSGD_TextureManager::GetInstance()->LoadTexture("resources/graphics/hud bar border.png", 0xffffffff);
		//CSGD_TextureManager::GetInstance()->Draw(hudborder,  0, 499);
		

		/*RECT rTOPfarLeft = {50, 501, 150, 533};
		RECT rTOPleft = {150, 501, 250, 533};
		RECT rTOPright = {250, 501, 350, 533};
		RECT rTOPfarRight = {350, 501, 450, 533};

		RECT rBOTTOMfarLeft  = { 50, 535, 150, 567};
		RECT rBOTTOMleft     = {150, 535, 250, 567};
		RECT rBOTTOMright    = {250, 535, 350, 567};
		RECT rBOTTOMfarRight = {350, 535, 450, 567};

		RECT rAbutton = { 83, 568, 115, 600};
		RECT rBbutton = {183, 568, 215, 600};
		RECT rXbutton = {283, 568, 315, 600};
		RECT rYbutton = {383, 568, 415, 600};
		CBitmapFont::GetInstance()->PrintInRect("Symbol of Fear", &rTOPfarLeft, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));
		CBitmapFont::GetInstance()->PrintInRect("Symbol of Fear", &rTOPleft, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));
		CBitmapFont::GetInstance()->PrintInRect("Symbol of Fear", &rTOPright, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));
		CBitmapFont::GetInstance()->PrintInRect("Symbol of Fear", &rTOPfarRight, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));*/

		/*CBitmapFont::GetInstance()->PrintInRect("Proximity Rune", &rBOTTOMfarLeft, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));
		CBitmapFont::GetInstance()->PrintInRect("Fireball", &rBOTTOMleft, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));
		CBitmapFont::GetInstance()->PrintInRect("Remote Rune", &rBOTTOMright, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));
		CBitmapFont::GetInstance()->PrintInRect("Healing Circle", &rBOTTOMfarRight, ALIGN_CENTER, D3DCOLOR_XRGB(255, 255, 255));*/

		

		// "icons"
		/*CHud::GetInstance()->SetYPosition("A button.png", 536);
		CHud::GetInstance()->SetYPosition("B button.png", 536);
		CHud::GetInstance()->SetYPosition("X button.png", 536);
		CHud::GetInstance()->SetYPosition("Y button.png", 536);

		CHud::GetInstance()->Draw("A button.png");
		CHud::GetInstance()->Draw("B button.png");
		CHud::GetInstance()->Draw("X button.png");
		CHud::GetInstance()->Draw("Y button.png");*/

		
		/*int AButton = CSGD_TextureManager::GetInstance()->LoadTexture("resources/graphics/A Button.png", 0xffffffff);
		int BButton = CSGD_TextureManager::GetInstance()->LoadTexture("resources/graphics/B Button.png", 0xffffffff);
		int XButton = CSGD_TextureManager::GetInstance()->LoadTexture("resources/graphics/X Button.png", 0xffffffff);
		int YButton = CSGD_TextureManager::GetInstance()->LoadTexture("resources/graphics/Y Button.png", 0xffffffff);
		CSGD_TextureManager::GetInstance()->Draw(AButton,  83, 568);
		CSGD_TextureManager::GetInstance()->Draw(BButton, 183, 568);
		CSGD_TextureManager::GetInstance()->Draw(XButton, 283, 568);
		CSGD_TextureManager::GetInstance()->Draw(YButton, 383, 568);*/
		///////////////////////////////////////
		//
		//	DEBUG DISPLAY
		//
		///////////////////////////////////////
		if (bDebugModeOn)
		{
			char buffer[128] = {0};
			char FPSbuffer[128];
			sprintf_s(buffer, _countof(buffer), "Objects in Object Manager: %i", CObjectManager::GetInstance()->GetSize(OMF_ALL) );
			CSGD_Direct3D::GetInstance()->DrawText(buffer, 0,0 );

			// Calculate the number of frames per one second:
			m_nFrameCounter++;
			m_dwCurrentTime = GetTickCount();//timeGetTime();
			m_dwElapsedTime = m_dwCurrentTime - m_dwLastUpdateTime;
			if (m_dwElapsedTime >= 1000)
			{
				m_nFrameCounter = 0;
				m_dwLastUpdateTime = m_dwCurrentTime;
			}
			sprintf_s(FPSbuffer, _countof(FPSbuffer), "FPS: %u", (UINT)(m_nFrameCounter * 1000.0 / m_dwElapsedTime) );
			CSGD_Direct3D::GetInstance()->DrawText(FPSbuffer, 0, 15 );
		}

		if (CSGD_DirectInput::GetInstance()->KeyPressed(DIK_F1))
		{
			CObjectManager::GetInstance()->PrintObjectsToConsole(OMF_ALL);
		}
//<<<<<<< .mine
//=======
//		
//>>>>>>> .r37
}
void CGamePlayState::Exit(void)
{
	//TODO:
	/*CSGD_EventSystem::GetInstance()->UnregisterClient("playerIsDead", this);
	CSGD_EventSystem::GetInstance()->UnregisterClient("toggleDebugDisplay.debug", this);
	CSGD_EventSystem::GetInstance()->UnregisterClient("bossIsDead.gameover", this);*/
	m_pES->UnregisterClient(REDUCE_ENEMY_HEALTH, this);

	CSGD_FModManager::GetInstance()->StopSound(m_nBGM[0]);
	CSGD_FModManager::GetInstance()->UnloadSound(m_nBGM[0]);
	//CSGD_ObjectManager::GetInstance()->RemoveAllObjects();

	if (m_pMS)
	{
		m_pMS->ShutdownMessageSystem();
		m_pMS = NULL;
	}

	if (m_pES)
	{
		m_pES->ShutdownEventSystem();
		m_pES = NULL;
	}

	//TODO: SAFE_RELEASE of object pointers
	
}

void CGamePlayState::MessageProc(CBaseMessage* pMsg)
{
	switch(pMsg->GetMsgID())
	{
	case MSG_CREATE_PLAYER:
		{
			CPlayer* pPlayer;

			CCreatePlayerMsg* pP = (CCreatePlayerMsg*)pMsg;

			pPlayer = (CPlayer*)CObjectFactory::GetInstance()->CreatePlayer();
			pPlayer->SetPosX(pP->GetPosX() );
			pPlayer->SetPosY(pP->GetPosY() );

			CObjectManager::GetInstance()->AddObject(pPlayer, OMF_PLAYER, RL_MAIN);

			pPlayer->Release();
		}
		break;

	case MSG_DESTROY_PLAYER:
		{
			CDestroyPlayerMsg* pP = (CDestroyPlayerMsg*)pMsg;

			CObjectManager::GetInstance()->RemoveObject(pP->GetPlayer() );
		}
		break;
	/*case MSG_PLAYERSHIP_FIRE_BLACK:
		{
			CBlackBullet* pBullet;

			CCreateBlackPlayerBulletMsg* pBB = (CCreateBlackPlayerBulletMsg*)pMsg;

			pBullet = (CBlackBullet*)CSGD_ObjectFactory<std::string,CBase>::GetInstance()->CreateObject("CBlackBullet");
			pBullet->SetPosX(pBB->GetPosX());
			pBullet->SetPosY(pBB->GetPosY());

			CSGD_ObjectManager::GetInstance()->AddObject(pBullet);

			pBullet->Release();
		}
		break;*/

	//case MSG_DESTROY_BLACK_PLAYER_BULLET:
	//	{
	//		CDestroyBlackPlayerBulletMsg* pBB = (CDestroyBlackPlayerBulletMsg*)pMsg;

	//		CSGD_ObjectManager::GetInstance()->RemoveObject( pBB->GetBullet() );

	//	}
	//	break;

	}
}

void CGamePlayState::HandleEvent(CEvent* pEvent)
{
	//TODO: handle events
}

// Plays a sound effect with the given sound ID at the passed volume setting and with panning
void CGamePlayState::PlayPannedSound (int nFModSoundID, float nSoundLocation)
{
	CSGD_FModManager::GetInstance()->SetVolume(nFModSoundID, CGame::GetInstance()->GetSFXVolume());
	CSGD_FModManager::GetInstance()->SetPan(nFModSoundID, nSoundLocation );
	CSGD_FModManager::GetInstance()->PlaySoundA(nFModSoundID);
}

void CGamePlayState::HandlePlayerOneInput()
{
	// LEFT
	if (CSGD_DirectInput::GetInstance()->KeyDown(DIK_A) )
	{
		m_pPlayerOne->SetPosX(m_pPlayerOne->GetPosX() - 4);
	}
	// RIGHT
	if (CSGD_DirectInput::GetInstance()->KeyDown(DIK_D) )
	{
		m_pPlayerOne->SetPosX(m_pPlayerOne->GetPosX() + 4);
	}
	// UP
	if (CSGD_DirectInput::GetInstance()->KeyDown(DIK_W) )
	{
		m_pPlayerOne->SetPosY(m_pPlayerOne->GetPosY() - 4);
	}
	// DOWN
	if (CSGD_DirectInput::GetInstance()->KeyDown(DIK_S) )
	{
		m_pPlayerOne->SetPosY(m_pPlayerOne->GetPosY() + 4);
	}

	// SPELL SLOT 1
	/*if (CSGD_DirectInput::GetInstance()->KeyDown(DIK_J) )
	{
		if (m_pPlayerOne->GetMana() >= m_pPlayerOne->GetSpellSlot(0)->
		m_pPlayerOne->GetSpellSlot(0)->Cast(m_pPlayerOne);
	}*/
}
// draws the HUD bar border, the Xbox 360 buttons, the player icons, and the radar
//void CGamePlayState::DrawHUDBar()
//{
//	CHud::GetInstance()->Draw("hud bar border.png");
//
//	// player one Xbox 360 buttons
//	CHud::GetInstance()->SetXPosition("A button.png",  83);
//	CHud::GetInstance()->SetXPosition("B button.png", 147);
//	CHud::GetInstance()->SetXPosition("X button.png", 211);
//	CHud::GetInstance()->SetXPosition("Y button.png", 275);
//
//	CHud::GetInstance()->SetYPosition("A button.png", 568);
//	CHud::GetInstance()->SetYPosition("B button.png", 568);
//	CHud::GetInstance()->SetYPosition("X button.png", 568);
//	CHud::GetInstance()->SetYPosition("Y button.png", 568);
//
//	CHud::GetInstance()->Draw("A button.png");
//	CHud::GetInstance()->Draw("B button.png");
//	CHud::GetInstance()->Draw("X button.png");
//	CHud::GetInstance()->Draw("Y button.png");
//
//	// player two Xbox 360 buttons
//	CHud::GetInstance()->SetXPosition("Y button.png", 686);
//	CHud::GetInstance()->SetXPosition("X button.png", 622);
//	CHud::GetInstance()->SetXPosition("B button.png", 558);
//	CHud::GetInstance()->SetXPosition("A button.png", 494);
//
//	CHud::GetInstance()->SetYPosition("A button.png", 568);
//	CHud::GetInstance()->SetYPosition("B button.png", 568);
//	CHud::GetInstance()->SetYPosition("X button.png", 568);
//	CHud::GetInstance()->SetYPosition("Y button.png", 568);
//
//	CHud::GetInstance()->Draw("A button.png");
//	CHud::GetInstance()->Draw("B button.png");
//	CHud::GetInstance()->Draw("X button.png");
//	CHud::GetInstance()->Draw("Y button.png");
//}
